package com.stars.easyms.redis.interceptor;

import com.stars.easyms.redis.annotion.RedisStringGet;
import com.stars.easyms.redis.exception.RedisInterceptorException;
import com.stars.easyms.base.util.GenericTypeUtil;
import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.concurrent.TimeUnit;

/**
 * <p>className: RedisStringGetInterceptor</p>
 * <p>description: RedisStringGet注解拦截器</p>
 *
 * @author guoguifang
 * @version 1.2.1
 * @date 2019-03-18 14:20
 */
public class RedisStringGetInterceptor extends AbstractRedisInterceptor<RedisStringGet> {

    @Override
    protected Object invoke(MethodInvocation methodInvocation, RedisStringGet redisStringGet) throws RedisInterceptorException {
        Object result;
        if (isEnabled()) {
            String redisKey = getRedisKey(methodInvocation, redisStringGet.group());
            Method pointMethod = methodInvocation.getMethod();
            Class<?> returnType = pointMethod.getReturnType();
            Type genericReturnType = pointMethod.getGenericReturnType();
            if (!(genericReturnType instanceof ParameterizedType)) {
                result = easyMsRedisTemplate.get(redisKey, returnType);
            } else {
                result = GenericTypeUtil.parseObject(easyMsRedisTemplate.get(redisKey), (ParameterizedType) genericReturnType, returnType);
            }
            if (result != null) {
                return result;
            }
            result = proceed(methodInvocation);
            if (result != null) {
                Long expire = getExpire(methodInvocation, redisStringGet.expire());
                if (expire != null && expire > 0) {
                    easyMsRedisTemplate.set(redisKey, result, expire, TimeUnit.MILLISECONDS);
                } else {
                    easyMsRedisTemplate.set(redisKey, result);
                }
            }
        } else {
            result = proceed(methodInvocation);
        }
        return result;
    }

}